/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "cast_engine_dlna_service_proxy.h"
#include "cast_engine_common.h"
#include "ui/rs_surface_node.h"
#include "surface_utils.h"
#include "window.h"
#include "cast_engine_log.h"
#include <cstdint>

namespace OHOS {
namespace CastEngine {
namespace CastEngineService {
DEFINE_CAST_ENGINE_LABEL("Cast-Engine-Dlna-Service-Proxy");

int32_t CastEngineDlnaServiceProxy::SendDmrPlayer(const sptr<IRemoteObject> &object)
{
    CLOGD("CastEngineDlnaServiceProxy::SendDmrPlayer");

    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }

    dataParcel.WriteRemoteObject(object);
    int error = Remote()->SendRequest(SEND_DMR_PLAYER, dataParcel, replyParcel, option);
    int32_t result = -1;
    result = (error == ERR_NONE) ? replyParcel.ReadInt32() : -1;
    return result;
}

int32_t CastEngineDlnaServiceProxy::Play()
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(PLAY, dataParcel, replyParcel, option);
    return result;
}

int32_t CastEngineDlnaServiceProxy::Pause()
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(PAUSE, dataParcel, replyParcel, option);
    return result;
}

int32_t CastEngineDlnaServiceProxy::Stop()
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(STOP, dataParcel, replyParcel, option);
    return result;
}

int32_t CastEngineDlnaServiceProxy::Forward(int &seconds)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    dataParcel.WriteInt32(seconds);
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(FORWORD, dataParcel, replyParcel, option);
    return result;
}

int32_t CastEngineDlnaServiceProxy::Backward(int &seconds)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    dataParcel.WriteInt32(seconds);
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(BACKWARD, dataParcel, replyParcel, option);
    return result;
}

int32_t CastEngineDlnaServiceProxy::GetPosition(int &position)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(GET_POSITION, dataParcel, replyParcel, option);
    result = replyParcel.ReadInt32(position);
    return position;
}

int32_t CastEngineDlnaServiceProxy::GetPlayerStatus(int32_t &playerStates)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(GET_PLAYER_STATUS, dataParcel, replyParcel, option);
    result = replyParcel.ReadInt32(playerStates);
    return playerStates;
}

int32_t CastEngineDlnaServiceProxy::GetDuration(int32_t &Duration)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(GET_DURATION, dataParcel, replyParcel, option);
    result = replyParcel.ReadInt32(Duration);
    return Duration;
}

int32_t CastEngineDlnaServiceProxy::Seek(int position)
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    dataParcel.WriteInt32(position);
    result = Remote()->SendRequest(SEEK, dataParcel, replyParcel, option);
    return result;
}

int32_t CastEngineDlnaServiceProxy::SetSurfaceId(std::string surfaceId)
{
    int32_t result = -1;
    uint64_t surfaceUniqueId = static_cast<uint64_t>(std::strtoll(surfaceId.c_str(), nullptr, 10));
    if (errno == ERANGE) {
        CLOGE("errno == ERANGE");
        return result;
    }

    sptr<Surface> surface = SurfaceUtils::GetInstance()->GetSurface(surfaceUniqueId);
    if (!surface) {
        CLOGE("surface is null, surface uniqueId %llu", surfaceUniqueId);
        return result;
    }
    sptr<IBufferProducer> producer = surface->GetProducer();
    if (!producer) {
        CLOGE("producer is null");
        return result;
    }

    MessageParcel data, reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(GetDescriptor())) {
        CLOGE("Failed to write the interface token");
        return result;
    }
    if (!data.WriteRemoteObject(producer->AsObject())) {
        CLOGE("Failed to write surface producer");
        return result;
    }

    result = Remote()->SendRequest(SET_SURFACE, data, reply, option);
    CLOGE("SendRequest SET_SURFACE ret:%{public}d",result);

    return result;
}

int32_t CastEngineDlnaServiceProxy::SetDmrSurface(sptr<IBufferProducer> producer)
{
    int32_t result = -1;
    MessageParcel data, reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(GetDescriptor())) {
        CLOGE("Failed to write the interface token");
        return result;
    }
    if (!data.WriteRemoteObject(producer->AsObject())) {
        CLOGE("Failed to write surface producer");
        return result;
    }

    result = Remote()->SendRequest(SET_SURFACE, data, reply, option);
    CLOGE("SendRequest SET_SURFACE ret:%{public}d",result);

    return result;

}

int32_t CastEngineDlnaServiceProxy::GetDlnaDeviceName(std::string &deviceName)
{

    int32_t result = -1;
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    result = Remote()->SendRequest(DLNA_GET_DEVICE_NAME, dataParcel, replyParcel, option);
    result = replyParcel.ReadString(deviceName);    
    CLOGD("CastEngineDlnaServiceProxy::GetDlnaDeviceName %{public}s",deviceName.c_str());

    return result;
}

int32_t CastEngineDlnaServiceProxy::SetDlnaDeviceName(const std::string &deviceName)
{

    int32_t result = -1;
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    if (!dataParcel.WriteString(deviceName)) {
        CLOGE("Failed to write surface producer");
        return result;
    }
    result = Remote()->SendRequest(DLNA_SET_DEVICE_NAME, dataParcel, replyParcel, option);
    CLOGE("SendRequest DLNA_SET_DEVICE_NAME ret:%{public}d",result);
    return result;
}

int32_t CastEngineDlnaServiceProxy::GetDmrState(DmrStates &dmrState)
{
    int32_t result = -1;
    int32_t tmp;
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    result = Remote()->SendRequest(DLNA_GET_DMR_STATES, dataParcel, replyParcel, option);
    result = replyParcel.ReadInt32(tmp);
    dmrState = static_cast<DmrStates>(tmp);

    return result;
}
int32_t CastEngineDlnaServiceProxy::GetVolume(int &volume, int &maxVolume)
{
    int32_t result = -1;
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    result = Remote()->SendRequest(DLNA_GET_VOLUME, dataParcel, replyParcel, option);
    result = replyParcel.ReadInt32(volume);
    result = replyParcel.ReadInt32(maxVolume);
    return result;
}

int32_t CastEngineDlnaServiceProxy::SetVolume(int volume)
{
    int32_t result = -1;
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    dataParcel.WriteInt32(volume);
    result = Remote()->SendRequest(DLNA_SET_VOLUME, dataParcel, replyParcel, option);

    return result;
}

int32_t CastEngineDlnaServiceProxy::AuthDeviceFail()
{
    MessageOption option;
    MessageParcel dataParcel, replyParcel;
    if (!dataParcel.WriteInterfaceToken(GetDescriptor())) {
        return ERR_INVALID_VALUE;
    }
    int32_t result = -1;
    result = Remote()->SendRequest(AUTH_DEVICE_FAIL, dataParcel, replyParcel, option);
    return result;
}

}// namespace CastEngineService
}// namespace CastEngine
}// namespace OHOS